// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Web.UI;
using CommunityServer.Components;
using CommunityServer.Controls;
using System.Text;
using System.IO;
using System.Collections.Specialized;
using System.ComponentModel;

namespace CommunityServerStuff.Controls
{
    /// <summary>
    /// The base IPager implemenation providing basic pager support.
    /// </summary>
    public abstract class PreTemplatedPagerBase : WrappedContentBase, IPager, IDataItemsContainer
    {
        #region Binding

        /// <summary>
        /// Binds the previous pager link.
        /// </summary>
        /// <param name="c">The control into which the previous pager link should be added.</param>
        protected virtual void BindPrevious(Control c)
        {
            if (PageIndex > 0)
            {
                if (this.PreviousLinkTemplate != null)
                {
                    WrappedControlItem item = new WrappedControlItem(new CSLink(ResourceManager.GetString("Utility_Pager_previousButton"), GetPageNavigateUrl(PageIndex)), 0, 0);
                    this.PreviousLinkTemplate.InstantiateIn(item);
                    c.Controls.Add(item);
                }
                else
                {
                    HyperLink link = new HyperLink();
                    link.Text = ResourceManager.GetString("Utility_Pager_previousButton");
                    link.NavigateUrl = GetPageNavigateUrl(PageIndex);
                    c.Controls.Add(link);
                }

           }

        }

        #endregion

        #region Helper methods

        /// <summary>
        /// Gets the initial page index.
        /// </summary>
        /// <returns></returns>
        protected abstract int GetInitialPageIndex();

        /// <summary>
        /// Gets the URL to navigate to the given page index.
        /// </summary>
        /// <param name="pageIndex">The page index.</param>
        /// <returns></returns>
        protected abstract string GetPageNavigateUrl(int pageIndex);

        #endregion

        #region Public Properties

        #region Templates

        /// <summary>
        /// Gets or sets the previous link template.
        /// </summary>
        /// <value>The previous link template.</value>
        [
        Browsable(false),
        DefaultValue(null),
        PersistenceMode(PersistenceMode.InnerProperty),
        ]
        public virtual ITemplate PreviousLinkTemplate
        {
            get { return _previousLinkTemplate; }
            set { _previousLinkTemplate = value; }
        }
        private ITemplate _previousLinkTemplate;

        /// <summary>
        /// Gets or sets the next link template.
        /// </summary>
        /// <value>The next link template.</value>
        [
        Browsable(false),
        DefaultValue(null),
        PersistenceMode(PersistenceMode.InnerProperty),
        ]
        public virtual ITemplate NextLinkTemplate
        {
            get { return _nextLinkTemplate; }
            set { _nextLinkTemplate = value; }
        }
        private ITemplate _nextLinkTemplate;

        #endregion

        /// <summary>
        /// Gets the total number of pages.
        /// </summary>
        /// <value>The total pages.</value>
        public virtual int TotalPages
        {
            get
            {
                int totalPagesAvailable;

                if (TotalRecords == 0 || PageSize == 0)
                    return 0;

                // First calculate the division
                //
                totalPagesAvailable = TotalRecords / PageSize;

                // Now do a mod for any remainder
                //
                if ((TotalRecords % PageSize) > 0)
                    totalPagesAvailable++;

                return totalPagesAvailable;
            }
        }

        int _pageIndex = -2;
        /// <summary>
        /// Gets or sets the current page index.
        /// </summary>
        /// <value>The page index.</value>
        public virtual int PageIndex
        {
            get
            {
                if (_pageIndex == -2)
                {
                    int pageIndex = GetInitialPageIndex();
                    if (pageIndex >= 0)
                    {
                        this.PageIndex = pageIndex;
                        PageIndexChanged(this, new PagerEventArgs(this.PageSize, pageIndex, this.TotalRecords));
                    }
                }

                if (_pageIndex < 0)
                    return 0;
                else
                    return _pageIndex;
            }
            set
            {
                _pageIndex = value;
            }
        }

        /// <summary>
        /// Gets or sets the number of items displayed on each page.
        /// </summary>
        /// <value>The size of the page.</value>
        public virtual int PageSize
        {
            get { return (int)(ViewState["PageSize"] ?? 10); }
            set { ViewState["PageSize"] = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether paging causes validation.
        /// </summary>
        /// <value><c>true</c> if paging causes validation; otherwise, <c>false</c>.</value>
        public virtual bool CausesValidation
        {
            get { return (bool)(ViewState["CausesValidation"] ?? true); }
            set { ViewState["CausesValidation"] = value; }
        }

        /// <summary>
        /// Gets or sets the total number of records.
        /// </summary>
        /// <value>The total records.</value>
        public virtual int TotalRecords
        {
            get { return (int)(ViewState["TotalRecords"] ?? 0); }
            set { ViewState["TotalRecords"] = value; }
        }

        /// <summary>
        /// Gets or sets the duration of the loading of the data being paged.
        /// </summary>
        /// <value>The duration.</value>
        public virtual double Duration
        {
            get { return (double)(ViewState["Duration"] ?? 0d); }
            set { ViewState["Duration"] = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether to show the next link.
        /// </summary>
        /// <value><c>true</c> if the next link is shown; otherwise, <c>false</c>.</value>
        public virtual bool ShowNext
        {
            get { return (bool)(ViewState["ShowNext"] ?? true); }
            set { ViewState["ShowNext"] = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether to show the previous link.
        /// </summary>
        /// <value><c>true</c> if the previous link is shown; otherwise, <c>false</c>.</value>
        public virtual bool ShowPrevious
        {
            get { return (bool)(ViewState["ShowPrevious"] ?? true); }
            set { ViewState["ShowPrevious"] = value; }
        }

        /// <summary>
        /// Gets the current page number.
        /// </summary>
        /// <value>The current page.</value>
        public virtual int CurrentPage
        {
            get { return this.PageIndex + 1; }
        }

        /// <summary>
        /// Gets or sets the number of individual page links to display.
        /// </summary>
        /// <value>The number of individual page links.</value>
        public virtual int IndividualPagesDisplayedCount
        {
            get { return (int)(ViewState["IndividualPagesDisplayedCount"] ?? 5); }
            set { ViewState["IndividualPagesDisplayedCount"] = value; }
        }

        #endregion

        #region Events

        /// <summary>
        /// Occurs when the page index changes.
        /// </summary>
        public event PagerEventHandler OnPageIndexChanged;

        protected void PageIndexChanged(IPager sender, PagerEventArgs e)
        {
            if (OnPageIndexChanged != null)
                OnPageIndexChanged(sender, e);
        }

        protected override void OnLoad(EventArgs e)
        {
            int pageIndex = GetInitialPageIndex();
            if (pageIndex >= 0)
            {
                this.PageIndex = pageIndex;
                PageIndexChanged(this, new PagerEventArgs(this.PageSize, pageIndex, this.TotalRecords));
            }

            base.OnLoad(e);
        }

        #endregion

        #region IDataItemsContainer Members

        public T GetDataItem<T>() where T : class
        {
            if (this is T)
                return this as T;
            else
                return null;
        }

        #endregion
    }
}